home *** CD-ROM | disk | FTP | other *** search
- #include "oracle.h"
-
- #define TRUE -1
- #define FALSE 0
-
- oracle::oracle(char *seed,int max_r_n_plus_1)
- // An eight (or fewer) character seed and the upper bound on the
- // numbers to be returned specify the random number generator.
- {
- modulus=max_r_n_plus_1;
- prime=equal_or_larger_prime(modulus);
- // A prime modulus is needed to insure that the number returned from
- // the random number generator are uniformly distributed.
- for (int r_n_index_1=0; ((r_n_index_1 < 8) && (seed[r_n_index_1]));
- r_n_index_1++) // insert seed
- {
- if (seed[r_n_index_1] < '\0')
- seed[r_n_index_1]=-seed[r_n_index_1];
- r_n[r_n_index_1]=long(seed[r_n_index_1])%prime;
- }
- int r_n_index_2=7;
- while (r_n_index_1 > 0) // right justify
- {
- r_n_index_1--;
- r_n[r_n_index_2]=r_n[r_n_index_1];
- r_n_index_2--;
- }
- while (r_n_index_2 >= 0) // fill with leading 1's
- {
- r_n[r_n_index_2]=1;
- r_n_index_2--;
- }
- }
-
- long oracle::equal_or_larger_prime(int starting_value)
- // Try consecutive values until a prime number is found.
- {
- long result=long(starting_value);
- while (! is_prime(result)) result++;
- return result;
- }
-
- int oracle::is_prime(long possible_prime)
- // If no number up to the square root of a number evenly divides the
- // number, then the number is prime.
- {
- long new_max_divisor;
- int result=TRUE;
- long max_divisor=possible_prime;
- int square_root=FALSE;
-
- while (! square_root)
- {
- if ((new_max_divisor=(max_divisor+possible_prime/max_divisor)/2l)
- < max_divisor)
- max_divisor=new_max_divisor;
- else
- square_root=TRUE;
- } // max_divisor=sqrt(possible_prime) via Newton's method.
- for (long divisor=2l; ((result) && (divisor <= max_divisor)); divisor++)
- result=((divisor*(possible_prime/divisor)) != possible_prime);
- return result;
- }
-
- int oracle::random_number()
- // Ignoring initialization, r_n[i] is the sum of the 8 previous values of
- // r_n[i] mod prime. r_n[7] is computed until it's within the desired range and
- // then it's returned.
- // It is assumed that a "long" can contain the sum of any two "int"s.
- {
- int r_n_index_1;
- int r_n_index_2;
- long result;
- long tem_long;
-
- do
- {
- result=r_n[0];
- r_n_index_1=0;
- r_n_index_2=1;
- while (r_n_index_2 < 8)
- {
- tem_long=r_n[r_n_index_2];
- r_n[r_n_index_1]=tem_long;
- result+=tem_long;
- if (result >= prime)
- result-=prime;
- r_n_index_1=r_n_index_2;
- r_n_index_2++;
- }
- r_n[7]=result;
- }
- while (result >= long(modulus));
- return int(result);
- }
-